#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "grouping.h"

// 自定义 strdup 实现
#ifndef HAVE_STRDUP
static char* custom_strdup(const char* s) {
    if (!s) return NULL;
    size_t len = strlen(s) + 1;
    char* dup = malloc(len);
    if (dup) {
        memcpy(dup, s, len);
    }
    return dup;
}
#define strdup custom_strdup
#endif

// 初始化分组表
static GroupTable* group_table_init() {
    GroupTable* gt = malloc(sizeof(GroupTable));
    if (!gt) return NULL;
    
    gt->group_capacity = 16;
    gt->group_count = 0;
    gt->groups = malloc(gt->group_capacity * sizeof(TemplateGroup*));
    if (!gt->groups) {
        free(gt);
        return NULL;
    }
    
    memset(gt->groups, 0, gt->group_capacity * sizeof(TemplateGroup*));
    return gt;
}

// 扩展分组表容量
static bool group_table_expand(GroupTable* gt) {
    uint32_t new_capacity = gt->group_capacity * 2;
    TemplateGroup** new_groups = realloc(gt->groups, new_capacity * sizeof(TemplateGroup*));
    if (!new_groups) return false;
    
    gt->groups = new_groups;
    memset(gt->groups + gt->group_capacity, 0, (new_capacity - gt->group_capacity) * sizeof(TemplateGroup*));
    gt->group_capacity = new_capacity;
    return true;
}

// 在分组表中查找分组
static int group_table_find(GroupTable* gt, const char* group_key) {
    for (uint32_t i = 0; i < gt->group_count; i++) {
        if (gt->groups[i] && strcmp(gt->groups[i]->group_key, group_key) == 0) {
            return i;
        }
    }
    return -1;
}

// 在分组表中添加新分组
static int group_table_add(GroupTable* gt, const char* group_key) {
    // 检查参数有效性
    if (!gt || !group_key) return -1;
    
    // 检查是否需要扩展
    if (gt->group_count >= gt->group_capacity) {
        if (!group_table_expand(gt)) {
            return -1;
        }
    }
    
    // 创建新分组
    TemplateGroup* new_group = malloc(sizeof(TemplateGroup));
    if (!new_group) return -1;
    
    // 初始化内存
    memset(new_group, 0, sizeof(TemplateGroup));
    
    new_group->group_key = strdup(group_key);
    if (!new_group->group_key) {
        free(new_group);
        return -1;
    }
    
    new_group->template_capacity = 8;
    new_group->template_count = 0;
    new_group->templates = malloc(new_group->template_capacity * sizeof(LogTemplate*));
    if (!new_group->templates) {
        free(new_group->group_key);
        free(new_group);
        return -1;
    }
    
    memset(new_group->templates, 0, new_group->template_capacity * sizeof(LogTemplate*));
    
    // 添加到分组表
    gt->groups[gt->group_count] = new_group;
    return gt->group_count++;
}

// 释放分组表资源
static void group_table_free(GroupTable* gt) {
    if (!gt) return;
    
    for (uint32_t i = 0; i < gt->group_count; i++) {
        if (gt->groups[i]) {
            free(gt->groups[i]->group_key);
            
            for (uint32_t j = 0; j < gt->groups[i]->template_count; j++) {
                if (gt->groups[i]->templates[j]) {
                    free(gt->groups[i]->templates[j]->template_str);
                    free(gt->groups[i]->templates[j]);
                }
            }
            
            free(gt->groups[i]->templates);
            free(gt->groups[i]);
        }
    }
    
    free(gt->groups);
    free(gt);
}

// 扩展模板组容量
static bool template_group_expand(TemplateGroup* group) {
    uint32_t new_capacity = group->template_capacity * 2;
    LogTemplate** new_templates = realloc(group->templates, new_capacity * sizeof(LogTemplate*));
    if (!new_templates) return false;
    
    group->templates = new_templates;
    memset(group->templates + group->template_capacity, 0, (new_capacity - group->template_capacity) * sizeof(LogTemplate*));
    group->template_capacity = new_capacity;
    return true;
}

// 初始化分组管理器
GroupManager* group_manager_init() {
    GroupManager* gm = malloc(sizeof(GroupManager));
    if (!gm) return NULL;
    
    // 配置HeavyGuardian（根据论文参数）
    HGConfig config = {
        .width = 1000,      // 哈希表宽度
        .depth = 1,         // 哈希表深度
        .heavy_size = 32,   // 高频项计数器数量
        .sparse_size = 4,   // 稀疏项计数器数量
        .decay_base = 1.08  // 指数衰减基数
    };
    
    gm->hg = hg_init(config);
    if (!gm->hg) {
        free(gm);
        return NULL;
    }
    
    // 初始化分组表
    gm->group_table = group_table_init();
    if (!gm->group_table) {
        hg_free(gm->hg);
        free(gm);
        return NULL;
    }
    
    return gm;
}

// 处理日志分词结果，返回分组ID
int group_manager_process(GroupManager* gm, const char** tokens, uint32_t token_count) {
    if (!gm || !tokens || token_count == 0) return -1;
    
    // 更新词频统计
    for (uint32_t i = 0; i < token_count; i++) {
        hg_insert(gm->hg, tokens[i]);
    }
    
    // 找出当前日志中频率最高的词作为分组关键词
    uint32_t max_freq = 0;
    const char* candidate = NULL;
    
    for (uint32_t i = 0; i < token_count; i++) {
        // 跳过变量标记（如<*>）
        if (strcmp(tokens[i], "<*>") == 0) continue;
        
        uint32_t freq = hg_query(gm->hg, tokens[i]);
        if (freq > max_freq) {
            max_freq = freq;
            candidate = tokens[i];
        }
    }
    
    // 如果没有找到合适的候选词，使用第一个非变量词
    if (!candidate) {
        for (uint32_t i = 0; i < token_count; i++) {
            if (strcmp(tokens[i], "<*>") != 0) {
                candidate = tokens[i];
                break;
            }
        }
    }
    
    if (!candidate) return -1;
    
    // 查找或创建分组
    int group_id = group_table_find(gm->group_table, candidate);
    if (group_id == -1) {
        group_id = group_table_add(gm->group_table, candidate);
    }
    
    return group_id;
}

// 根据分组ID获取分组
TemplateGroup* group_manager_get_group(GroupManager* gm, int group_id) {
    if (!gm) {
        printf("Group manager is NULL\n");
        return NULL;
    }
    
    if (group_id < 0) {
        printf("Invalid group_id: %d\n", group_id);
        return NULL;
    }
    
    if ((uint32_t)group_id >= gm->group_table->group_count) {
        printf("Group_id %d out of range (max: %u)\n", 
               group_id, gm->group_table->group_count - 1);
        return NULL;
    }
    
    TemplateGroup* group = gm->group_table->groups[group_id];
    if (!group) {
        printf("Group at index %d is NULL\n", group_id);
    }
    
    return group;
}

// 向分组添加模板
bool group_manager_add_template(GroupManager* gm, int group_id, const char* template_str) {
    TemplateGroup* group = group_manager_get_group(gm, group_id);
    if (!group || !template_str) return false;
    
    // 检查是否需要扩展
    if (group->template_count >= group->template_capacity) {
        if (!template_group_expand(group)) {
            return false;
        }
    }
    
    // 创建新模板
    LogTemplate* new_template = malloc(sizeof(LogTemplate));
    if (!new_template) return false;
    
    new_template->template_str = strdup(template_str);
    if (!new_template->template_str) {
        free(new_template);
        return false;
    }
    
    new_template->ref_count = 1;
    
    // 添加到分组
    group->templates[group->template_count++] = new_template;
    return true;
}

// 释放分组管理器资源
void group_manager_free(GroupManager* gm) {
    if (!gm) return;
    
    hg_free(gm->hg);
    group_table_free(gm->group_table);
    free(gm);
}

// 获取分组表信息（用于调试）
void group_manager_print_groups(const GroupManager* gm) {
    if (!gm) return;
    
    printf("Group Table (%u groups):\n", gm->group_table->group_count);
    for (uint32_t i = 0; i < gm->group_table->group_count; i++) {
        TemplateGroup* group = gm->group_table->groups[i];
        if (group) {
            printf("  Group %u: key='%s', templates=%u\n", i, group->group_key, group->template_count);
            for (uint32_t j = 0; j < group->template_count; j++) {
                if (group->templates[j]) {
                    printf("    Template %u: %s\n", j, group->templates[j]->template_str);
                }
            }
        }
    }
}